﻿using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;



namespace Typo3ImageUpload
{
    class T3Connector
    {
        private String t3path;
        private String t3user;
        private String t3pass;

        private static T3Connector theInstance;

        /// <summary>
        /// Singelton
        /// </summary>
        /// <returns>aktives T3Connector-Objekt</returns>
        public static T3Connector getInstance()
        {
            return theInstance;
        }


        public T3Connector(String path, String user, String pwd) {
            //Singleton set
            theInstance = this;

            //try
            //{
                t3user = user;
                t3pass = pwd;
                t3path = checkPath(path);
                checkAuth();
            /*}
            catch (Exception ex){
                Console.WriteLine("Fehler beim Starten: "+ex);
                //this = null;
            }*/
        }
        
        /**
         * Berechtigung prüfen
         */
        public Boolean checkAuth()
        {
            String param = "&login=" + t3user + "&kennwort=" + t3pass;
            String action = "chkauth";

            String xmlres = connectT3(action, param);
            Hashtable hdlres = handleXmlRes(xmlres);
            String errors = (String) hdlres["errors"];
            if (errors.Equals(""))
            { //OK 
                Console.WriteLine("FILEMOUNTS" + hdlres["filemounts"]);
                return true;
            }
            else {
                throw new Exception(errors);
                //return false;
            }
        }

        public String getFilemounts()
        {
            String param = "&login=" + t3user + "&kennwort=" + t3pass;
            String action = "chkauth";

            String xmlres = connectT3(action, param);
            Hashtable hdlres = handleXmlRes(xmlres);
            String errors = (String)hdlres["errors"];
            if (errors.Equals(""))
            { //OK 
                return (String) hdlres["filemounts"];
            }
            else
            {
                throw new Exception(errors);
            }
        }

        private Hashtable handleXmlRes(string xmlres)
        {
            //Errors, Filemounts
            String errs = "";
            String fms = "";
            Console.WriteLine("XML:" + xmlres);
            
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(xmlres);
            XmlNodeList errors = xDoc.GetElementsByTagName("error");
            XmlNodeList filemounts = xDoc.GetElementsByTagName("t3filemount");
            //NodeList nodes = document.SelectNodes("//t3filemounts");
            
            for(int i=0;i<errors.Count;i++){
                Console.WriteLine("ERROR:" + errors[i].InnerText);
                errs += errors[i].InnerText + ",";
            }
            for(int i=0;i<filemounts.Count;i++)
            {
                Console.WriteLine("Filemount:" + filemounts[i].InnerXml);
                fms += filemounts[i].InnerXml + ",";
            }
            //Response verpacken
            Hashtable response = new Hashtable();
            response.Add("errors", errs);
            response.Add("filemounts", "<fileadmin>"+fms+"</fileadmin>");

            return response;
        }
        
        private String checkPath(String path)
        {
            //Prüfen ob Punkt vorhanden
            if (!(path.IndexOf(".") > 0)) {
                throw new Exception("INVALID_URL");
                //return null;
            }

            //Evtl. http:// vornheran setzen
            if (!path.Substring(0, 7).Equals("http://") || !path.Substring(0, 7).Equals("https://"))
            {
                path = "http://" + path;
            }

            //URL hinten anängen
            if (!path.Substring(path.Length - 2).Equals("/")) {
                path += "/";
            }
            //path += "imgupp.php";
            path += "typo3conf/ext/fag_imgappupload/res/appConnector.php";

            return path;
        }

        private String connectT3(String action, String param)
        {
            Stream os = null;
            String Response = null;

            //Params
            String parameter = "action="+action+"&"+param;
            Console.WriteLine("PARAMETER:" + parameter);
            byte[] bytes = Encoding.ASCII.GetBytes(parameter);
            
            //Webrequest
            WebRequest webRequest = WebRequest.Create(t3path);
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.Method = "POST";
            
            try
            { // POST SENDEN
                webRequest.ContentLength = bytes.Length;
                os = webRequest.GetRequestStream();
                os.Write(bytes, 0, bytes.Length);
            }
            catch (WebException ex){
                Console.WriteLine(ex.Message, "HttpPost: Request error");
            }
            finally{
                if (os != null){
                    os.Close();
                }
            }

            try
            { // ANWORT ERHALTEN
                WebResponse webResponse = webRequest.GetResponse();
                if (webResponse == null)
                {
                    //return null; 
                }
                StreamReader sr = new StreamReader(webResponse.GetResponseStream());
                Response = sr.ReadToEnd().Trim();
            }
            catch (WebException ex)
            {
                Console.WriteLine(ex.Message, "HttpPost: Response error");
            }
            
            return Response;
        }

        private bool quickConnectT3(String action, String param)
        {
            String response = connectT3(action, param);
            Hashtable ht = handleXmlRes(response);

            String errors = (String) ht["errors"];
            if (errors.Equals(""))
            {
                return true;
            }
            else {
                throw new Exception(errors);
            }
        }
        
        public bool uploadImage(String uploadpath, String image)
        {
            //Pfad checken, später evtl. mit t3connector
            if (uploadpath.Equals(""))
            {
                throw new T3Exception("PATH_INVALID");
            }

            try
            {

                WebClient InsertClient = new WebClient();
                InsertClient.Encoding = Encoding.UTF8;
                
                String param = "action=imageUpload";
                param += "&path="+uploadpath;
                param += "&login=" + t3user;
                byte[] Response = InsertClient.UploadFile(t3path+"?"+param, "POST", image);
                Hashtable xmlhdl = handleXmlRes(Encoding.ASCII.GetString(Response));
                Console.WriteLine(Encoding.ASCII.GetString(Response));
                
                if (xmlhdl["errors"].Equals("")){
                    return true;
                }
                else{
                    throw new T3Exception((String) xmlhdl["errors"]);
                }
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);
                return false;
            }
        }


        public bool changeDir(String path, String newName, String oldName)
        {
            try
            {
                quickConnectT3("changeDir", "path=" + path+"&newName="+newName+"&oldName="+oldName);
                return true;
            }
            catch (T3Exception ex)
            {
                throw new T3Exception(ex.Message);
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
                return false;
            }
        }

    }



    /**
         * T3Exception
         */
    class T3Exception : Exception
    {
        public T3Exception()
        {

        }
        public T3Exception(string message) : base("T3:"+message)
        {
            
        }
    }
}
